package cn.xo68.ide.plugin.common.jobs;

import cn.xo68.core.PropertiesDocument;
import cn.xo68.core.common.Charsets;
import cn.xo68.core.util.JsonUtil;
import cn.xo68.ide.plugin.common.PluginConstants;
import cn.xo68.ide.plugin.common.component.StarupApplicationComponent;
import cn.xo68.ide.plugin.common.domain.ProjectInfo;
import cn.xo68.ide.plugin.common.job.JobCallback;
import cn.xo68.ide.plugin.common.job.ToolSuiteJob;
import com.intellij.ide.impl.NewProjectUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.projectImport.ProjectOpenProcessor;
import com.wy2.generator.GenerateResult;
import com.wy2.generator.ProjectGenerator;
import com.wy2.generator.config.GeneratorConsts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.LinkedList;
import java.util.Map;

public class CreateProjectJob implements ToolSuiteJob {
    private static Logger logger = LoggerFactory.getLogger(CreateProjectJob.class);

    private final String title;
    private final Map<String, Object> config;
    private final Project selectedProject;
    private final VirtualFile operateVirtualFile;
    private final JobCallback jobCallback;

    public CreateProjectJob(String title, Map<String, Object> config, Project selectedProject, VirtualFile operateVirtualFile) {
        this.title = title;
        this.config = config;
        this.selectedProject = selectedProject;
        this.operateVirtualFile = operateVirtualFile;
        this.jobCallback= new JobCallbackImpl();
    }

    @Override
    public String getTitle() {
        return title;
    }

    @Override
    public boolean isModal() {
        return true;
    }

    @Override
    public boolean isStartInBackground() {
        return true;
    }

    @Override
    public JobCallback getCallback() {
        return this.jobCallback;
    }

    @Override
    public void execute(ProgressIndicator indicator) throws Exception {
        PropertiesDocument prop=new PropertiesDocument(true);
        prop.setProperty(GeneratorConsts.GENERATOR_CONFIG_TEMPLATE_DIRECTORY, (String) config.get(GeneratorConsts.GENERATOR_CONFIG_TEMPLATE_DIRECTORY));

        File projectDirectory=new File((String) config.get(GeneratorConsts.GENERATOR_CONFIG_OUTPUT_DIRECTORY));
        if(!projectDirectory.exists()) {
            projectDirectory.mkdirs();
        }
        prop.setProperty(GeneratorConsts.GENERATOR_CONFIG_OUTPUT_DIRECTORY, (String) config.get(GeneratorConsts.GENERATOR_CONFIG_OUTPUT_DIRECTORY));
        prop.setProperty(GeneratorConsts.GENERATOR_CONFIG_ENCODING, Charsets.UTF8);
        prop.setProperty(GeneratorConsts.GENERATOR_CONFIG_TEMPLATE_SUFFIX,GeneratorConsts.GENERATOR_CONFIG_TEMPLATE_SUFFIX_DEFAULT);
        ProjectGenerator projectGenerator=new ProjectGenerator(prop);

        LinkedList<GenerateResult> generateResults =projectGenerator.generate(config, true);
        logger.info("{}",projectGenerator.getOutputRootDirectory());
        generateResults.forEach(result->{
            logger.info("{} - {} - {} - {}",result.getMarker(), result.getSuccess(), result.getMarge(),result.getGenerateFilePath());
        });

        ProjectInfo projectInfo= JsonUtil.getInstance().load(new File(projectDirectory,(String) config.get(GeneratorConsts.TEMPLATE_ATTRI_ARTIFACT_ID)+File.separator+ PluginConstants.GENERATE_PROJECT_INFO_FILE), Charsets.UTF8, ProjectInfo.class);
        if(projectInfo==null) {
            logger.error("创建项目 失败，原因是：{}","项目模板异常,缺少"+PluginConstants.GENERATE_PROJECT_INFO_FILE);
            return;
        }




    }

    private class JobCallbackImpl implements JobCallback {

        @Override
        public void success() {
            logger.info("项目创建成功");
            ApplicationManager.getApplication().invokeLater(()-> {
                StarupApplicationComponent.getInstance().getProject().getBaseDir().refresh(false,false);
                Messages.showMessageDialog(
                        config.get(GeneratorConsts.TEMPLATE_ATTRI_ARTIFACT_ID) + "项目创建成功"
                        , "项目创建成功"
                        , Messages.getInformationIcon());

                String operatePath = operateVirtualFile.getCanonicalPath();
                String selectedPath = (String) config.get(GeneratorConsts.GENERATOR_CONFIG_OUTPUT_DIRECTORY);
                logger.info("当前操作目录：{},生成项目目录：{}",operatePath,selectedPath);
                if(selectedPath.equals(operatePath)){
                    // 模块
                    operateVirtualFile.refresh(false, true);
                }else {
                    // 项目
                    File file = new File(selectedPath, (String) config.get(GeneratorConsts.TEMPLATE_ATTRI_ARTIFACT_ID));
                    VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(file.getAbsolutePath());
                    ProjectOpenProcessor[] arrs = Extensions.getExtensions(ProjectOpenProcessor.EXTENSION_POINT_NAME);
                    for (ProjectOpenProcessor projectOpenProcessor :
                            arrs) {
                        if (projectOpenProcessor.toString().contains("MavenProjectOpenProcessor")) {
                            NewProjectUtil.closePreviousProject(selectedProject);
                            projectOpenProcessor.doOpenProject(virtualFile, selectedProject, true);
                            break;
                        }
                    }
                }
            });

        }

        @Override
        public void fail(Throwable e) {
            logger.error("项目创建失败",e);
            ApplicationManager.getApplication().invokeLater(()-> {
                Messages.showMessageDialog(
                        config.get(GeneratorConsts.TEMPLATE_ATTRI_ARTIFACT_ID) + "项目创建失败"
                        , "项目创建失败"
                        , Messages.getErrorIcon());


            });
        }
    }
}
